package com.eternal.base.data;

import androidx.lifecycle.LiveData;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;

import com.eternal.base.LivePagedBuilder;
import com.eternal.base.concat.DeviceInfo;
import com.eternal.base.concat.TmpHum;
import com.eternal.base.data.ble.BleStatue;
import com.eternal.base.data.ble.IBleControl;
import com.eternal.base.data.source.IHistorySource;
import com.eternal.base.database.entity.History;
import com.eternal.base.global.BluetoothKey;

import java.util.List;

import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.ObservableSource;
import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class HistoryRepository extends BaseRepository {
    private IHistorySource source;
    private PagedList.Config historyConfig;

    public HistoryRepository(IHistorySource source, IBleControl control) {
        super(control);
        this.source = source;
    }

    public Completable refreshHistory(final String mac) {
        final BleStatue statue = getConnect(mac);
        if (statue != null) {
            if (statue.getType() == BluetoothKey.DEVICE_TYPE_A || statue.getType() == BluetoothKey.DEVICE_TYPE_B || statue.getType() == BluetoothKey.DEVICE_TYPE_E) {
                return refreshHistory(statue);
            } else {
                return refreshCHistory(statue);
            }
        }
        return Completable.complete();
    }

    private Completable refreshHistory(final BleStatue statue) {
        return Single.create(new SingleOnSubscribe<Long>() {
            @Override
            public void subscribe(SingleEmitter<Long> emitter) {
                emitter.onSuccess(source.getTime(statue.getMac()));
            }
        }).flatMapObservable(new Function<Long, ObservableSource<History>>() {
            @Override
            public ObservableSource<History> apply(Long aLong) {
                if (aLong == 0) {
                    aLong = 946656000000L;
                }
                if (statue.getType() == BluetoothKey.DEVICE_TYPE_E) {
                    return control.getEHistory(statue, aLong);
                } else {
                    return control.getHistory(statue, aLong);
                }
            }
        }).observeOn(Schedulers.io()).doOnNext(new Consumer<History>() {
            @Override
            public void accept(History history) {
                if (history.hum <= 10000) {
                    try {
                        history.mac = statue.getMac();
                        source.add(history);
                    } catch (Exception e) {
                    }
                }
            }
        }).ignoreElements();
    }

    private Completable refreshCHistory(final BleStatue statue) {
        return Single.create(new SingleOnSubscribe<Long>() {
            @Override
            public void subscribe(@NonNull SingleEmitter<Long> emitter) {
                emitter.onSuccess(source.getTime(statue.getMac()));
            }
        }).flatMapObservable(new Function<Long, ObservableSource<History>>() {
            @Override
            public ObservableSource<History> apply(@NonNull Long aLong) {
                return control.getCHistory(statue, (aLong/1000 - 1577808000) / 60);
            }
        }).observeOn(Schedulers.io()).doOnNext(new Consumer<History>() {
            @Override
            public void accept(History history) throws Exception {
                if (history.hum <= 10000) {
                    try {
                        history.mac = statue.getMac();
                        history.time = history.time * 60 + 1577808000;
                        source.add(history);
                    } catch (Exception e) {
                    }
                }
            }
        }).ignoreElements();
    }

    public Flowable<DeviceInfo> getInfo(String mac) {
        return source.getInfo(mac);
    }

    public LiveData<PagedList<TmpHum>> getHistory(String mac) {
        return new LivePagedBuilder<>(source.getHistory(mac), getHistoryConfig()).build();
    }

    public LiveData<PagedList<TmpHum>> getHistory(String mac, long start, long end) {
        return new LivePagedListBuilder<>(source.getHistory(mac, start, end), getExportConfig()).build();
    }

    public LiveData<PagedList<TmpHum>> getHistoryMin(String mac, List<String> times, long start, long end) {
        return new LivePagedListBuilder<>(source.getHistoryMin(mac, times, start, end),
                getExportConfig()).build();
    }

    public LiveData<PagedList<TmpHum>> getHistoryHour(String mac, List<String> times, String min, long start, long end) {
        return new LivePagedListBuilder<>(source.getHistoryHour(mac, times, min, start, end),
                getExportConfig()).build();
    }

    private PagedList.Config getExportConfig() {
        return new PagedList.Config.Builder()
                .setPageSize(20)
                .setEnablePlaceholders(true)
                .setInitialLoadSizeHint(20).build();
    }

    private PagedList.Config getHistoryConfig() {
        if (historyConfig == null) {
            historyConfig = new PagedList.Config.Builder()
                    .setPageSize(525600/2)
                    .setEnablePlaceholders(false)
                    .setInitialLoadSizeHint(525600).build();
        }
        return historyConfig;
    }

    public long getLastTime(String mac) {
        return source.getTime(mac);
    }

    public Long getFirstTime(String mac) {
        return source.getFirstTime(mac);
    }

}